home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 24
/
AACD 24.iso
/
AACD
/
Resources
/
Online
/
OpenURL
/
Developer
/
Source
/
library_api.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-26
|
11KB
|
444 lines
/*
** openurl.library - universal URL display and browser launcher library
** Written by Troels Walsted Hansen <troels@thule.no>
** Placed in the public domain.
**
** Main module for the library with all API functions.
*/
#include "library_common.h"
#include "library_api.h"
#include "library_prefs.h"
#include "library_util.h"
#include "handler.h"
/**************************************************************************
*
* Global variables.
*
*/
struct DosLibrary *DOSBase = NULL;
struct Library *UtilityBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *IFFParseBase = NULL;
struct RxsLib *RexxSysBase = NULL;
struct URL_Prefs *Prefs = NULL;
struct SignalSemaphore PrefsSemaphore, HandlerSemaphore;
struct Process *HandlerProcess = NULL;
struct MsgPort *HandlerMsgPort;
/**************************************************************************
*
* SAS/C library functions.
*
*/
LIB int __UserLibInit(REG(a6) struct Library *OpenURLBase)
{
int retval = 1;
BPTR seglist;
struct MsgPort *mp = NULL;
struct HandlerMsg hm = {0};
/* run time initialized globals */
SysBase = *(struct ExecBase **)4;
InitSemaphore(&PrefsSemaphore);
InitSemaphore(&HandlerSemaphore);
/* open libraries */
if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36)))
goto done;
if(!(UtilityBase = OpenLibrary("utility.library", 36)))
goto done;
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 36)))
goto done;
if(!(IFFParseBase = OpenLibrary("iffparse.library", 36)))
goto done;
if(!(RexxSysBase = (struct RxsLib *)OpenLibrary("rexxsyslib.library", 33)))
goto done;
/* load prefs */
if(!LoadPrefs(PREFS_NAME_USE) && !(Prefs = LIB_URL_GetDefaultPrefs()))
goto done;
/* load and launch handler */
if(!(mp = CreateMsgPort()))
goto done;
if(!(seglist = LoadSeg("L:OpenURL-Handler")))
{
struct EasyStruct es;
es.es_StructSize = sizeof(struct EasyStruct);
es.es_Flags = 0;
es.es_Title = "OpenURL Error";
es.es_TextFormat = "openurl.library was unable to load\n"
"L:OpenURL-Handler into memory.\n"
"Please reinstall.";
es.es_GadgetFormat = "Ok";
EasyRequestArgs(NULL, &es, NULL, NULL);
goto done;
}
HandlerProcess = CreateNewProcTags(NP_Seglist, seglist,
NP_Name, "OpenURL ARexx Handler",
NP_Priority, 0,
NP_StackSize, 4096,
NP_Input, NULL,
NP_Output, NULL,
NP_CloseInput, FALSE,
NP_CloseOutput, FALSE,
NP_CurrentDir, NULL,
NP_HomeDir, NULL,
NP_CopyVars, FALSE,
TAG_DONE);
if(!HandlerProcess)
{
UnLoadSeg(seglist);
goto done;
}
/* use a startup msg to synchronize with the handler */
hm.hm_Msg.mn_ReplyPort = mp;
hm.hm_Msg.mn_Length = sizeof(struct HandlerMsg);
hm.hm_Type = HMT_STARTUP;
hm.hm_Semaphore = &HandlerSemaphore;
PutMsg(&(HandlerProcess->pr_MsgPort), (struct Message *)&hm);
WaitPort(mp);
GetMsg(mp);
/* check that handler initialized its resources correctly */
if(!hm.hm_Success)
{
HandlerProcess = NULL;
goto done;
}
HandlerMsgPort = hm.hm_MsgPort;
retval = 0;
done:
if(mp) DeleteMsgPort(mp);
if(retval) __UserLibCleanup(OpenURLBase);
return(retval);
}
/**************************************************************************/
LIB void __UserLibCleanup(REG(a6) struct Library *OpenURLBase)
{
/* shutdown handler process */
if(!AttemptSemaphore(&HandlerSemaphore))
{
/* process is still alive, and holding semaphore.
signal it to terminate */
Signal((struct Task *)HandlerProcess, SIGBREAKF_CTRL_C);
}
else ReleaseSemaphore(&HandlerSemaphore);
/* free other resources */
if(Prefs) LIB_URL_FreePrefs(Prefs);
CloseLibrary((struct Library *)RexxSysBase);
CloseLibrary(IFFParseBase);
CloseLibrary((struct Library *)IntuitionBase);
CloseLibrary(UtilityBase);
CloseLibrary((struct Library *)DOSBase);
}
/**************************************************************************
*
* Library functions available through API.
*
*/
LIB BOOL LIB_URL_OpenA(REG(a0) STRPTR url, REG(a1) struct TagItem *tags)
{
BOOL retval = FALSE;
struct List portlist;
struct MsgPort *mp;
STRPTR fullurl = NULL;
BOOL Show, ToFront, NewWindow, Launch;
BOOL http_prepend = FALSE;
/* some initialization */
NewList(&portlist);
ObtainSemaphore(&PrefsSemaphore);
if(!(mp = CreateMsgPort()))
goto done;
/* parse the arguments */
Show = GetTagData(URL_Show, Prefs->up_DefShow, tags);
ToFront = GetTagData(URL_BringToFront, Prefs->up_DefBringToFront, tags);
NewWindow = GetTagData(URL_NewWindow, Prefs->up_DefNewWindow, tags);
Launch = GetTagData(URL_Launch, Prefs->up_DefLaunch, tags);
/* make a copy of the global list of named ports */
Forbid();
retval = CopyList(&portlist, &SysBase->PortList, sizeof(struct Node));
Permit();
if(!retval) goto done;
/* prepend "http://" if URL has no method */
if(Prefs->up_Flags & UPF_PREPENDHTTP)
{
STRPTR colon;
colon = strchr(url, ':');
if(!colon)
http_prepend = TRUE;
else
{
STRPTR p;
for(p = url; p < colon; p++)
{
if(!isalnum(*p) && (*p != '+') && (*p != '-'))
{
http_prepend = TRUE;
break;
}
}
}
}
if(http_prepend)
{
if(!(fullurl = AllocVec(strlen(url) + 8, MEMF_PUBLIC)))
goto done;
SPrintf(fullurl, "http://%s", url);
}
else fullurl = url;
/* mailto: or generic URL? */
if((Prefs->up_Flags & UPF_DOMAILTO) && !strncmp(url, "mailto:", 7))
retval = SendToMailer(fullurl, &portlist, mp, Show, ToFront, Launch);
else
retval = SendToBrowser(fullurl, &portlist, mp, Show, ToFront, NewWindow, Launch);
done:
ReleaseSemaphore(&PrefsSemaphore);
FreeList(&portlist, sizeof(struct Node));
if(mp) DeleteMsgPort(mp);
if(http_prepend && fullurl) FreeVec(fullurl);
return(retval);
}
/**************************************************************************/
LIB struct URL_Prefs *LIB_URL_GetPrefs(VOID)
{
struct URL_Prefs *p;
/* make a copy of the prefs structure and return that */
ObtainSemaphoreShared(&PrefsSemaphore);
p = CopyPrefs(Prefs);
ReleaseSemaphore(&PrefsSemaphore);
return(p);
}
/**************************************************************************/
LIB VOID LIB_URL_FreePrefs(REG(a0) struct URL_Prefs *up)
{
/* free a prefs structure */
FreeList((struct List *)&up->up_BrowserList, sizeof(struct URL_BrowserNode));
FreeList((struct List *)&up->up_MailerList, sizeof(struct URL_MailerNode));
FreeMem(up, sizeof(struct URL_Prefs));
}
/**************************************************************************/
LIB BOOL LIB_URL_SetPrefs(REG(a0) struct URL_Prefs *p, REG(d0) BOOL permanent)
{
BOOL retval = FALSE;
struct URL_Prefs *new_p;
ObtainSemaphore(&PrefsSemaphore);
/* copy prefs structure */
if(!(new_p = CopyPrefs(p)))
goto done;
if(new_p->up_Version > PREFS_VERSION)
goto done;
if(new_p->up_Version < 2)
SetDefaultPrefsV2(new_p);
if(new_p->up_Version == 2)
ConvertPrefsV2toV3(Prefs);
if(new_p->up_Version < 3)
SetDefaultPrefsV3(new_p);
new_p->up_Version = PREFS_VERSION;
new_p->up_Flags &= ~UPF_ISDEFAULTS;
LIB_URL_FreePrefs(Prefs);
Prefs = new_p;
/* and save it to disk */
if(!SavePrefs(PREFS_NAME_USE, Prefs)) goto done;
if(permanent && !SavePrefs(PREFS_NAME_SAVE, Prefs))
goto done;
retval = TRUE;
done:
ReleaseSemaphore(&PrefsSemaphore);
return(retval);
}
/**************************************************************************/
LIB struct URL_Prefs *LIB_URL_GetDefaultPrefs(VOID)
{
struct URL_Prefs *p;
if(!(p = AllocMem(sizeof(struct URL_Prefs), MEMF_CLEAR)))
return(NULL);
p->up_Version = PREFS_VERSION;
p->up_Flags |= UPF_ISDEFAULTS;
if(!SetDefaultPrefsV1(p))
{
LIB_URL_FreePrefs(p);
return(NULL);
}
SetDefaultPrefsV2(p);
if(!SetDefaultPrefsV3(p))
{
LIB_URL_FreePrefs(p);
return(NULL);
}
return(p);
}
/**************************************************************************/
LIB BOOL LIB_URL_LaunchPrefsApp(VOID)
{
char path[256];
if(GetVar("OpenURL_Prefs_Path", path, sizeof(path), 0) == -1)
strcpy(path, "SYS:Prefs/OpenURL");
if(SystemTags(path,
SYS_Asynch, TRUE,
SYS_Input, Open("NIL:", MODE_NEWFILE),
SYS_Output, NULL,
TAG_END) == -1)
return(FALSE);
else
return(TRUE);
}
/**************************************************************************/
ASM ULONG a0hack(REG(d0) ULONG return1, REG(a0) UBYTE *return2)
{
/* lame hack to return an argstring in A0 as arexx expects */
return(return1);
}
LIB ULONG LIB_DoFunction(REG(a0) struct RexxMsg *rxmsg)
{
UBYTE *argstr;
STRPTR resstr;
/* check validity of rexx msg */
if(!rxmsg || !IsRexxMsg(rxmsg) || !(rxmsg->rm_Action & RXFUNC) ||
!rxmsg->rm_Args[0])
{
return(ERR10_010); /* invalid message packet */
}
/* check that we recognise the command */
if(!stricmp(rxmsg->rm_Args[0], "OPENURL"))
{
struct TagItem tags[MAXRMARG + 1];
STRPTR url = NULL;
int i, j;
/* parse the arguments (ReadArgs would be overkill for this) */
for(i = 1, j = 0; rxmsg->rm_Args[i] && j < MAXRMARG; i++)
{
Tag tag;
if(!stricmp(rxmsg->rm_Args[i], "SHOW") || !stricmp(rxmsg->rm_Args[i], "NOSHOW"))
tag = URL_Show;
else if(!stricmp(rxmsg->rm_Args[i], "TOFRONT") || !stricmp(rxmsg->rm_Args[i], "NOTOFRONT"))
tag = URL_BringToFront;
else if(!stricmp(rxmsg->rm_Args[i], "NEWWIN") || !stricmp(rxmsg->rm_Args[i], "NONEWWIN"))
tag = URL_NewWindow;
else if(!stricmp(rxmsg->rm_Args[i], "LAUNCH") || !stricmp(rxmsg->rm_Args[i], "NOLAUNCH"))
tag = URL_Launch;
else
{
url = rxmsg->rm_Args[i];
continue;
}
tags[j].ti_Tag = tag;
tags[j].ti_Data = strnicmp(rxmsg->rm_Args[i], "NO", 2);
j++;
}
tags[j].ti_Tag = TAG_END;
if(url && LIB_URL_OpenA(url, tags))
resstr = "1";
else
resstr = "0";
}
else if(!stricmp(rxmsg->rm_Args[0], "OPENURLPREFS"))
{
if(LIB_URL_LaunchPrefsApp())
resstr = "1";
else
resstr = "0";
}
else
return(ERR10_001); /* program not found */
if(!(argstr = CreateArgstring(resstr, 1)))
return(ERR10_003); /* no memory available */
return(a0hack(0, argstr));
}